package cn.mihoyo.base.service.impl;

import cn.mihoyo.base.dto.EmailRegisterDto;
import cn.mihoyo.base.dto.PhoneRegisterDto;
import cn.mihoyo.base.service.VerifyCodeService;
import cn.mihoyo.base.util.EmailUtil;
import cn.mihoyo.base.util.StrUtils;
import cn.mihoyo.base.util.VerifyCodeUtils;
import cn.mihoyo.user.domain.User;
import cn.mihoyo.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String imageCodeKey(String imageCodeKey) throws IOException {
        String complexRandomString = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(imageCodeKey,complexRandomString);
        String base64 = VerifyCodeUtils.VerifyCode(100, 30, complexRandomString);
        return base64;
    }

    @Override
    public void smsCode(PhoneRegisterDto dto) {
        if ("binder".equals(dto.getType())) {
            sendSms(dto,"binder:");
        } else if ("register".equals(dto.getType())) {
            if (StringUtils.isBlank(dto.getImageCodeKey()) || StringUtils.isBlank(dto.getImageCodeValue())) {
                throw new RuntimeException("验证码为空请重试");
            }
            verify(dto);
            sendSms(dto,"register:");
        }
    }

    private void sendSms(PhoneRegisterDto dto,String redisKey) {
//        "register:"
        Long expire = redisTemplate.getExpire(String.format(redisKey, dto.getPhone()));
        if(expire >= (3-1)*60){
            throw new RuntimeException("验证码超时请重试");
        }
        String smsCode  = (String) redisTemplate.opsForValue().get(String.format(redisKey, dto.getPhone()));
        if(StringUtils.isBlank(smsCode)){
            smsCode = StrUtils.getRandomString(4);
        }
        redisTemplate.opsForValue().set(String.format(redisKey, dto.getPhone()), smsCode, 3, TimeUnit.MINUTES);
        log.info("手机验证码为:{}",smsCode);
    }

    private void verify(PhoneRegisterDto dto) {
        //参数校验
        //验证手机号是否已经注册过
        User user = userMapper.findByPhone(dto.getPhone());
        if(user !=null){
           throw new RuntimeException("该手机号已经注册过了，请登录去");
        }
        //判断图形验证码是否正确
        Long expire = redisTemplate.getExpire(String.format("register:", dto.getPhone()));
        if(expire >= 2 * 60){
            throw new RuntimeException("这个验证码过期了，请重试");
        }
    }

    @Override
    public String emailImageCode(String imageCodeKey) throws IOException {
        String complexRandomString = StrUtils.getComplexRandomString(1);
        redisTemplate.opsForValue().set(imageCodeKey,complexRandomString);
        String base64 = VerifyCodeUtils.VerifyCode(100, 30, complexRandomString);
        return base64;
    }

    @Override
    public void EeailsmsCode(EmailRegisterDto dto) {
        // 非空校验
        String redisEmailImageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if (StringUtils.isBlank(redisEmailImageCode) || !redisEmailImageCode.equalsIgnoreCase(dto.getImageCodeValue())) {
            throw new RuntimeException("图形验证码错误！");
        }

        // 判断邮箱号是否注册过 去user表中找是否存在
        User user = userMapper.findByEmail(dto.getEmail());
        if (user != null) {
            throw new RuntimeException("该邮箱号已经注册过，请去登录！");
        }
        // 删除图形验证码
        redisTemplate.delete(dto.getImageCodeKey());
        // 两次发送时间是否大于60s
        Long expire = redisTemplate.getExpire(String.format("register:", dto.getEmail()));
        if (expire != null && expire >= (2) * 60) {
            throw new RuntimeException("请勿频繁获取邮箱验证码！");
        }
        String eailCode = StrUtils.getRandomString(4);
        // 邮箱验证码使用Redis进行存储 设置3分钟超时
        redisTemplate.opsForValue().set(String.format("register:", dto.getEmail())
                ,eailCode,3,TimeUnit.MINUTES);
          // 发送邮件
//        EmailUtil.sendEmail("1754165180@qq.com",
//                "1754165180@qq.com",
//                "1754165180@qq.com",
//                "vmpcdkjiuwxxefbg",
//                "宠物之家审核通知邮件",
//                "<h1>您好您的邮箱验证码为：</h1>" +
//                        eailCode);
//        MailUtils.sendMail(dto.getEmail(),"您的邮箱验证码是："+emailCode,"宠物之家验证信息");
        log.info("邮箱验证码是：{}", eailCode);
    }
}
